home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / jpeg / jpegsrc4 / jwrjfif.c < prev    next >
C/C++ Source or Header  |  1992-08-03  |  12KB  |  480 lines

  1. /*
  2.  * jwrjfif.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to write standard JPEG file headers/markers.
  9.  * The file format created is a raw JPEG data stream with (optionally) an
  10.  * APP0 marker per the JFIF spec.  This will handle baseline and
  11.  * JFIF-convention JPEG files, although there is currently no provision
  12.  * for inserting a thumbnail image in the JFIF header.
  13.  *
  14.  * These routines may need modification for non-Unix environments or
  15.  * specialized applications.  As they stand, they assume output to
  16.  * an ordinary stdio stream.  However, the changes to write to something
  17.  * else are localized in the macros appearing just below.
  18.  *
  19.  * These routines are invoked via the methods write_file_header,
  20.  * write_scan_header, write_jpeg_data, write_scan_trailer, and
  21.  * write_file_trailer.
  22.  */
  23.  
  24. #include "jinclude.h"
  25.  
  26. #ifdef JFIF_SUPPORTED
  27.  
  28.  
  29. /*
  30.  * To output to something other than a stdio stream, you'd need to redefine
  31.  * these macros.
  32.  */
  33.  
  34. /* Write a single byte */
  35. #define emit_byte(cinfo,x)  putc((x), cinfo->output_file)
  36.  
  37. /* Write some bytes from a (char *) buffer */
  38. #define WRITE_BYTES(cinfo,dataptr,datacount)  \
  39.   { if (JFWRITE(cinfo->output_file, dataptr, datacount) \
  40.     != (size_t) (datacount)) \
  41.       ERREXIT(cinfo->emethods, "Output file write error"); }
  42.  
  43. /* Clean up and verify successful output */
  44. #define CHECK_OUTPUT(cinfo)  \
  45.   { fflush(cinfo->output_file); \
  46.     if (ferror(cinfo->output_file)) \
  47.       ERREXIT(cinfo->emethods, "Output file write error"); }
  48.  
  49.  
  50. /* End of stdio-specific code. */
  51.  
  52.  
  53. typedef enum {            /* JPEG marker codes */
  54.   M_SOF0  = 0xc0,
  55.   M_SOF1  = 0xc1,
  56.   M_SOF2  = 0xc2,
  57.   M_SOF3  = 0xc3,
  58.   
  59.   M_SOF5  = 0xc5,
  60.   M_SOF6  = 0xc6,
  61.   M_SOF7  = 0xc7,
  62.   
  63.   M_JPG   = 0xc8,
  64.   M_SOF9  = 0xc9,
  65.   M_SOF10 = 0xca,
  66.   M_SOF11 = 0xcb,
  67.   
  68.   M_SOF13 = 0xcd,
  69.   M_SOF14 = 0xce,
  70.   M_SOF15 = 0xcf,
  71.   
  72.   M_DHT   = 0xc4,
  73.   
  74.   M_DAC   = 0xcc,
  75.   
  76.   M_RST0  = 0xd0,
  77.   M_RST1  = 0xd1,
  78.   M_RST2  = 0xd2,
  79.   M_RST3  = 0xd3,
  80.   M_RST4  = 0xd4,
  81.   M_RST5  = 0xd5,
  82.   M_RST6  = 0xd6,
  83.   M_RST7  = 0xd7,
  84.   
  85.   M_SOI   = 0xd8,
  86.   M_EOI   = 0xd9,
  87.   M_SOS   = 0xda,
  88.   M_DQT   = 0xdb,
  89.   M_DNL   = 0xdc,
  90.   M_DRI   = 0xdd,
  91.   M_DHP   = 0xde,
  92.   M_EXP   = 0xdf,
  93.   
  94.   M_APP0  = 0xe0,
  95.   M_APP15 = 0xef,
  96.   
  97.   M_JPG0  = 0xf0,
  98.   M_JPG13 = 0xfd,
  99.   M_COM   = 0xfe,
  100.   
  101.   M_TEM   = 0x01,
  102.   
  103.   M_ERROR = 0x100
  104. } JPEG_MARKER;
  105.  
  106.  
  107. LOCAL void
  108. emit_marker (compress_info_ptr cinfo, JPEG_MARKER mark)
  109. /* Emit a marker code */
  110. {
  111.   emit_byte(cinfo, 0xFF);
  112.   emit_byte(cinfo, mark);
  113. }
  114.  
  115.  
  116. LOCAL void
  117. emit_2bytes (compress_info_ptr cinfo, int value)
  118. /* Emit a 2-byte integer; these are always MSB first in JPEG files */
  119. {
  120.   emit_byte(cinfo, (value >> 8) & 0xFF);
  121.   emit_byte(cinfo, value & 0xFF);
  122. }
  123.  
  124.  
  125. LOCAL int
  126. emit_dqt (compress_info_ptr cinfo, int index)
  127. /* Emit a DQT marker */
  128. /* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
  129. {
  130.   QUANT_TBL_PTR data = cinfo->quant_tbl_ptrs[index];
  131.   int prec = 0;
  132.   int i;
  133.   
  134.   for (i = 0; i < DCTSIZE2; i++) {
  135.     if (data[i] > 255)
  136.       prec = 1;
  137.   }
  138.  
  139.   emit_marker(cinfo, M_DQT);
  140.   
  141.   emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
  142.   
  143.   emit_byte(cinfo, index + (prec<<4));
  144.   
  145.   for (i = 0; i < DCTSIZE2; i++) {
  146.     if (prec)
  147.       emit_byte(cinfo, data[i] >> 8);
  148.     emit_byte(cinfo, data[i] & 0xFF);
  149.   }
  150.  
  151.   return prec;
  152. }
  153.  
  154.  
  155. LOCAL void
  156. emit_dht (compress_info_ptr cinfo, int index, boolean is_ac)
  157. /* Emit a DHT marker */
  158. {
  159.   HUFF_TBL * htbl;
  160.   int length, i;
  161.   
  162.   if (is_ac) {
  163.     htbl = cinfo->ac_huff_tbl_ptrs[index];
  164.     index += 0x10;        /* output index has AC bit set */
  165.   } else {
  166.     htbl = cinfo->dc_huff_tbl_ptrs[index];
  167.   }
  168.  
  169.   if (htbl == NULL)
  170.     ERREXIT1(cinfo->emethods, "Huffman table 0x%02x was not defined", index);
  171.   
  172.   if (! htbl->sent_table) {
  173.     emit_marker(cinfo, M_DHT);
  174.     
  175.     length = 0;
  176.     for (i = 1; i <= 16; i++)
  177.       length += htbl->bits[i];
  178.     
  179.     emit_2bytes(cinfo, length + 2 + 1 + 16);
  180.     emit_byte(cinfo, index);
  181.     
  182.     for (i = 1; i <= 16; i++)
  183.       emit_byte(cinfo, htbl->bits[i]);
  184.     
  185.     for (i = 0; i < length; i++)
  186.       emit_byte(cinfo, htbl->huffval[i]);
  187.     
  188.     htbl->sent_table = TRUE;
  189.   }
  190. }
  191.  
  192.  
  193. LOCAL void
  194. emit_dac (compress_info_ptr cinfo)
  195. /* Emit a DAC marker */
  196. /* Since the useful info is so small, we want to emit all the tables in */
  197. /* one DAC marker.  Therefore this routine does its own scan of the table. */
  198. {
  199.   char dc_in_use[NUM_ARITH_TBLS];
  200.   char ac_in_use[NUM_ARITH_TBLS];
  201.   int length, i;
  202.   
  203.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  204.     dc_in_use[i] = ac_in_use[i] = 0;
  205.   
  206.   for (i = 0; i < cinfo->num_components; i++) {
  207.     dc_in_use[cinfo->comp_info[i].dc_tbl_no] = 1;
  208.     ac_in_use[cinfo->comp_info[i].ac_tbl_no] = 1;
  209.   }
  210.   
  211.   length = 0;
  212.   for (i = 0; i < NUM_ARITH_TBLS; i++)
  213.     length += dc_in_use[i] + ac_in_use[i];
  214.   
  215.   emit_marker(cinfo, M_DAC);
  216.   
  217.   emit_2bytes(cinfo, length*2 + 2);
  218.   
  219.   for (i = 0; i < NUM_ARITH_TBLS; i++) {
  220.     if (dc_in_use[i]) {
  221.       emit_byte(cinfo, i);
  222.       emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
  223.     }
  224.     if (ac_in_use[i]) {
  225.       emit_byte(cinfo, i + 0x10);
  226.       emit_byte(cinfo, cinfo->arith_ac_K[i]);
  227.     }
  228.   }
  229. }
  230.  
  231.  
  232. LOCAL void
  233. emit_dri (compress_info_ptr cinfo)
  234. /* Emit a DRI marker */
  235. {
  236.   emit_marker(cinfo, M_DRI);
  237.   
  238.   emit_2bytes(cinfo, 4);    /* fixed length */
  239.  
  240.   emit_2bytes(cinfo, (int) cinfo->restart_interval);
  241. }
  242.  
  243.  
  244. LOCAL void
  245. emit_sof (compress_info_ptr cinfo, JPEG_MARKER code)
  246. /* Emit a SOF marker */
  247. {
  248.   int i;
  249.   
  250.   emit_marker(cinfo, code);
  251.   
  252.   emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
  253.  
  254.   if (cinfo->image_height > 65535L || cinfo->image_width > 65535L)
  255.     ERREXIT(cinfo->emethods, "Maximum image dimension for JFIF is 65535 pixels");
  256.  
  257.   emit_byte(cinfo, cinfo->data_precision);
  258.   emit_2bytes(cinfo, (int) cinfo->image_height);
  259.   emit_2bytes(cinfo, (int) cinfo->image_width);
  260.  
  261.   emit_byte(cinfo, cinfo->num_components);
  262.  
  263.   for (i = 0; i < cinfo->num_components; i++) {
  264.     emit_byte(cinfo, cinfo->comp_info[i].component_id);
  265.     emit_byte(cinfo, (cinfo->comp_info[i].h_samp_factor << 4)
  266.              + cinfo->comp_info[i].v_samp_factor);
  267.     emit_byte(cinfo, cinfo->comp_info[i].quant_tbl_no);
  268.   }
  269. }
  270.  
  271.  
  272. LOCAL void
  273. emit_sos (compress_info_ptr cinfo)
  274. /* Emit a SOS marker */
  275. {
  276.   int i;
  277.   
  278.   emit_marker(cinfo, M_SOS);
  279.   
  280.   emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
  281.   
  282.   emit_byte(cinfo, cinfo->comps_in_scan);
  283.   
  284.   for (i = 0; i < cinfo->comps_in_scan; i++) {
  285.     emit_byte(cinfo, cinfo->cur_comp_info[i]->component_id);
  286.     emit_byte(cinfo, (cinfo->cur_comp_info[i]->dc_tbl_no << 4)
  287.              + cinfo->cur_comp_info[i]->ac_tbl_no);
  288.   }
  289.  
  290.   emit_byte(cinfo, 0);        /* Spectral selection start */
  291.   emit_byte(cinfo, DCTSIZE2-1);    /* Spectral selection end */
  292.   emit_byte(cinfo, 0);        /* Successive approximation */
  293. }
  294.  
  295.  
  296. LOCAL void
  297. emit_jfif_app0 (compress_info_ptr cinfo)
  298. /* Emit a JFIF-compliant APP0 marker */
  299. {
  300.   /*
  301.    * Length of APP0 block    (2 bytes)
  302.    * Block ID            (4 bytes - ASCII "JFIF")
  303.    * Zero byte            (1 byte to terminate the ID string)
  304.    * Version Major, Minor    (2 bytes - 0x01, 0x01)
  305.    * Units            (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
  306.    * Xdpu            (2 bytes - dots per unit horizontal)
  307.    * Ydpu            (2 bytes - dots per unit vertical)
  308.    * Thumbnail X size        (1 byte)
  309.    * Thumbnail Y size        (1 byte)
  310.    */
  311.   
  312.   emit_marker(cinfo, M_APP0);
  313.   
  314.   emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
  315.  
  316.   emit_byte(cinfo, 0x4A);    /* Identifier: ASCII "JFIF" */
  317.   emit_byte(cinfo, 0x46);
  318.   emit_byte(cinfo, 0x49);
  319.   emit_byte(cinfo, 0x46);
  320.   emit_byte(cinfo, 0);
  321.   emit_byte(cinfo, 1);        /* Major version */
  322.   emit_byte(cinfo, 1);        /* Minor version */
  323.   emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
  324.   emit_2bytes(cinfo, (int) cinfo->X_density);
  325.   emit_2bytes(cinfo, (int) cinfo->Y_density);
  326.   emit_byte(cinfo, 0);        /* No thumbnail image */
  327.   emit_byte(cinfo, 0);
  328. }
  329.  
  330.  
  331. /*
  332.  * Write the file header.
  333.  */
  334.  
  335.  
  336. METHODDEF void
  337. write_file_header (compress_info_ptr cinfo)
  338. {
  339.   char qt_in_use[NUM_QUANT_TBLS];
  340.   int i, prec;
  341.   boolean is_baseline;
  342.   
  343.   emit_marker(cinfo, M_SOI);    /* first the SOI */
  344.  
  345.   if (cinfo->write_JFIF_header)    /* next an optional JFIF APP0 */
  346.     emit_jfif_app0(cinfo);
  347.  
  348.   /* Emit DQT for each quantization table. */
  349.   /* Note that doing it here means we can't adjust the QTs on-the-fly. */
  350.   /* If we did want to do that, we'd have a problem with checking precision */
  351.   /* for the is_baseline determination. */
  352.  
  353.   for (i = 0; i < NUM_QUANT_TBLS; i++)
  354.     qt_in_use[i] = 0;
  355.  
  356.   for (i = 0; i < cinfo->num_components; i++)
  357.     qt_in_use[cinfo->comp_info[i].quant_tbl_no] = 1;
  358.  
  359.   prec = 0;
  360.   for (i = 0; i < NUM_QUANT_TBLS; i++) {
  361.     if (qt_in_use[i])
  362.       prec += emit_dqt(cinfo, i);
  363.   }
  364.   /* now prec is nonzero iff there are any 16-bit quant tables. */
  365.  
  366.   /* Check for a non-baseline specification. */
  367.   /* Note we assume that Huffman table numbers won't be changed later. */
  368.   is_baseline = TRUE;
  369.   if (cinfo->arith_code || (cinfo->data_precision != 8))
  370.     is_baseline = FALSE;
  371.   for (i = 0; i < cinfo->num_components; i++) {
  372.     if (cinfo->comp_info[i].dc_tbl_no > 1 || cinfo->comp_info[i].ac_tbl_no > 1)
  373.       is_baseline = FALSE;
  374.   }
  375.   if (prec && is_baseline) {
  376.     is_baseline = FALSE;
  377.     /* If it's baseline except for quantizer size, warn the user */
  378.     TRACEMS(cinfo->emethods, 0,
  379.         "Caution: quantization tables are too coarse for baseline JPEG");
  380.   }
  381.  
  382.  
  383.   /* Emit the proper SOF marker */
  384.   if (cinfo->arith_code)
  385.     emit_sof(cinfo, M_SOF9);    /* SOF code for arithmetic coding */
  386.   else if (is_baseline)
  387.     emit_sof(cinfo, M_SOF0);    /* SOF code for baseline implementation */
  388.   else
  389.     emit_sof(cinfo, M_SOF1);    /* SOF code for non-baseline Huffman file */
  390. }
  391.  
  392.  
  393. /*
  394.  * Write the start of a scan (everything through the SOS marker).
  395.  */
  396.  
  397. METHODDEF void
  398. write_scan_header (compress_info_ptr cinfo)
  399. {
  400.   int i;
  401.  
  402.   if (cinfo->arith_code) {
  403.     /* Emit arith conditioning info.  We will have some duplication
  404.      * if the file has multiple scans, but it's so small it's hardly
  405.      * worth worrying about.
  406.      */
  407.     emit_dac(cinfo);
  408.   } else {
  409.     /* Emit Huffman tables.  Note that emit_dht takes care of
  410.      * suppressing duplicate tables.
  411.      */
  412.     for (i = 0; i < cinfo->comps_in_scan; i++) {
  413.       emit_dht(cinfo, cinfo->cur_comp_info[i]->dc_tbl_no, FALSE);
  414.       emit_dht(cinfo, cinfo->cur_comp_info[i]->ac_tbl_no, TRUE);
  415.     }
  416.   }
  417.  
  418.   /* Emit DRI if required --- note that DRI value could change for each scan.
  419.    * If it doesn't, a tiny amount of space is wasted in multiple-scan files.
  420.    * We assume DRI will never be nonzero for one scan and zero for a later one.
  421.    */
  422.   if (cinfo->restart_interval)
  423.     emit_dri(cinfo);
  424.  
  425.   emit_sos(cinfo);
  426. }
  427.  
  428.  
  429. /*
  430.  * Write some bytes of compressed data within a scan.
  431.  */
  432.  
  433. METHODDEF void
  434. write_jpeg_data (compress_info_ptr cinfo, char *dataptr, int datacount)
  435. {
  436.   WRITE_BYTES(cinfo, dataptr, datacount);
  437. }
  438.  
  439.  
  440. /*
  441.  * Finish up after a compressed scan (series of write_jpeg_data calls).
  442.  */
  443.  
  444. METHODDEF void
  445. write_scan_trailer (compress_info_ptr cinfo)
  446. {
  447.   /* no work needed in this format */
  448. }
  449.  
  450.  
  451. /*
  452.  * Finish up at the end of the file.
  453.  */
  454.  
  455. METHODDEF void
  456. write_file_trailer (compress_info_ptr cinfo)
  457. {
  458.   emit_marker(cinfo, M_EOI);
  459.   /* Make sure we wrote the output file OK */
  460.   CHECK_OUTPUT(cinfo);
  461. }
  462.  
  463.  
  464. /*
  465.  * The method selection routine for standard JPEG header writing.
  466.  * This should be called from c_ui_method_selection if appropriate.
  467.  */
  468.  
  469. GLOBAL void
  470. jselwjfif (compress_info_ptr cinfo)
  471. {
  472.   cinfo->methods->write_file_header = write_file_header;
  473.   cinfo->methods->write_scan_header = write_scan_header;
  474.   cinfo->methods->write_jpeg_data = write_jpeg_data;
  475.   cinfo->methods->write_scan_trailer = write_scan_trailer;
  476.   cinfo->methods->write_file_trailer = write_file_trailer;
  477. }
  478.  
  479. #endif /* JFIF_SUPPORTED */
  480.